package com.ktjiaoyu.server.config.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtTokenUtil {
    private static final String CLAIM_KEY_USERNAEM = "sub"; // sub为载荷中面向的用户

    @Value("${jwt.expiration}")
    public Long expiration;
    @Value("${jwt.secret}")
    public String secret;

    //1.生成token
    public String genegrateToken(UserDetails userDetails){
        // 不要在 setXxx 之后调用 setClaims(Map<String, Object> claims)，
        // 因为这个方法会覆盖所有已设置的claim
        Map<String,Object> map=new HashMap<>();
        map.put(CLAIM_KEY_USERNAEM,userDetails.getUsername());
        String token = Jwts.builder()
                .setExpiration(new Date(System.currentTimeMillis()+expiration*1000))
                .addClaims(map)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
        return token;
    }

    //2.解析token
    public String getUserNameFromToken(String token){
        Claims claim = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
        return (String)claim.get(CLAIM_KEY_USERNAEM);
    }

    //2.解析token
    public Date getExpiredDateFromToken(String token){
        Claims claim = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
        return claim.getExpiration();
    }

    public boolean ValidateToken(String token, UserDetails userDetails) {
        String userName = getUserNameFromToken(token);
        // token中的用户名与UserDetails中保存用户名是否相等
        boolean flag = userName.equals(userDetails.getUsername());
        // 判断当前token是否失效, isTokenExpired()的结果：true表示已过期，false表示没有过期
        Date expireDate = getExpiredDateFromToken(token);
        boolean isFlag = !expireDate.before(new Date());
        return flag && isFlag;
    }

}
